﻿using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using SmartCity.Shared;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace MetroManagement
{
    /// <summary>
    /// 站点应用服务类
    /// </summary>
    public class MetroAppService : ApplicationService, IMetroAppService
    {
        private readonly IRepository<Line, int> _lineRepository;
        private readonly IRepository<Station, int> _stationRepository;
        private readonly IRepository<LineStation> _lineStationRepository;

        public MetroAppService(
            IRepository<Line, int> lineRepository,
            IRepository<Station, int> stationRepository,
            IRepository<LineStation> lineStationRepository)
        {
            _lineRepository = lineRepository;
            _stationRepository = stationRepository;
            _lineStationRepository = lineStationRepository;
        }

        // 列表
        public async Task<ResultResponse<IList<MetroDto>>> ListAsync(string currentName)
        {
            // 查询站点
            var query = await _stationRepository
                .WithDetailsAsync(m => m.LineStations);
            var station = query
                .Single(m => m.Name == currentName);
            // 查询线路
            var lineStations = station.LineStations;
            var dtos = new List<MetroDto>(lineStations.Count());
            foreach (var lineStation in lineStations)
            {
                var line = await _lineRepository
                    .GetAsync(lineStation.LineId);
                var lineStationQuery = await _lineStationRepository
                    .WithDetailsAsync(m => m.Line, m => m.Station);
                UniteStationDto preStationDto;
                var preLineStation = await lineStationQuery
                    .SingleOrDefaultAsync(m => m.LineId == line.Id && m.Seq == lineStation.Seq - 1);
                if (preLineStation != null)
                {
                    var preStationLines = await lineStationQuery
                        .Where(m => m.StationId == preLineStation.StationId)
                        .Select(m => m.Line)
                        .ToListAsync();
                    var preStationLinesDto = ObjectMapper.Map<List<Line>, List<SimpleLineDto>>(preStationLines);
                    preStationDto = new UniteStationDto()
                    {
                        Name = preLineStation.Station.Name,
                        Lines = preStationLinesDto
                    };
                }
                else
                {
                    preStationDto = null;
                }
                UniteStationDto nextStationDto;
                var nextLineStation = await lineStationQuery
                    .SingleOrDefaultAsync(m => m.LineId == line.Id && m.Seq == lineStation.Seq + 1);
                if (nextLineStation != null)
                {
                    var nextStationLines = await lineStationQuery
                        .Where(m => m.StationId == nextLineStation.StationId)
                        .Select(m => m.Line)
                        .ToListAsync();
                    var nextStationLinesDto = ObjectMapper.Map<List<Line>, List<SimpleLineDto>>(nextStationLines);
                    nextStationDto = new UniteStationDto()
                    {
                        Name = nextLineStation.Station.Name,
                        Lines = nextStationLinesDto
                    };
                }
                else
                {
                    nextStationDto = null;
                }
                var dto = new MetroDto()
                {
                    LineId = line.Id,
                    LineName = line.Name,
                    CurrentName = currentName,
                    ReachTime = 7,
                    PreStep = preStationDto,
                    NextStep = nextStationDto
                };
                dtos.Add(dto);
            }
            // 返回结果
            return ResultResponse<IList<MetroDto>>.Successful(dtos);
        }
    }
}